<template>
  <div class="popup" v-show="isShow">
    <div class="popup_header">
      监测到帧率较低!<span class="input-wraper"
        >当前帧率:<span class="input">{{ frameRate }}</span></span
      >
      <!-- <span class="input-wraper"
        >报警时帧率:<span class="input">{{ warnFrame }}</span></span
      > -->
    </div>
    <div class="popup_body">
      <div class="info">
        建议通过以下方式来提升帧率，如果当前帧数稳定，运行流畅，也可以<span
          style="cursor: pointer; color: #0ff"
          @click="close"
          >忽略该警报</span
        >
      </div>
      <div class="info">1: 通过降低整体清晰度(分辨率):</div>
      <div class="input-wraper">
        <span style="width: 120px">清晰度:</span>
        <span style="width: 30px">模糊</span>
        <el-slider
          style="width: 250px"
          :step="0.01"
          :max="1"
          :min="0"
          v-model="resolutionScale"
          size="small"
          @input="onChangeResolutionScale"
        />
        <span style="width: 30px; padding-left: 10px">清晰</span>
      </div>
      <div class="info">2: 通过降低模型清晰度:</div>
      <div>
        另外如果您的显存较低，且模型占用显存过高，建议设置更低的最大显存
      </div>
      <el-table
        class="table"
        :data="tableData"
        row-class-name="table-row"
        cell-class-name="table-cell"
        header-row-class-name="table-header-row"
        header-cell-class-name="table-header-cell"
      >
        <el-table-column prop="name" label="名称"></el-table-column>
        <el-table-column prop="maximumScreenSpaceError" label="清晰度">
          <template #default="scope">
            <div class="flex-center" style="width: 213px">
              <span style="width: 30px">模糊</span>
              <el-slider
                style="width: 150px"
                :show-tooltip="false"
                :step="1"
                :max="128"
                :min="0"
                v-model="scope.row.maximumScreenSpaceError"
                @input="changeMaximumScreenSpaceError($event, scope.row)"
                size="small"
              />
              <span style="width: 30px; padding-left: 10px">清晰</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="size" label="占用显存"></el-table-column>
        <el-table-column prop="maximumMemoryUsage" label="最大显存占用">
          <template #default="scope">
            <div class="flex-center" style="width: 210px">
              <el-slider
                style="width: 150px"
                :step="1"
                :max="4096"
                :min="512"
                v-model="scope.row.maximumMemoryUsage"
                @input="changeProperty($event, scope.row, 'maximumMemoryUsage')"
                size="small"
              />
              <span style="width: 60px"
                >{{ scope.row.maximumMemoryUsage }}MB</span
              >
            </div>
          </template>
        </el-table-column>
      </el-table>
      <div class="info">
        3:
        如果您的电脑配置过低。建议锁定一个较小的帧率，可以改善页面卡顿的问题，并且将报警阙值调低，避免频繁报警
      </div>
      <div class="input-wraper">
        <span style="width: 120px">报警触发阈值:</span>
        <el-slider
          style="width: 250px"
          :step="1"
          :min="0"
          :max="30"
          v-model="minimumFrameRateAfterWarmup"
          size="small"
          @input="onChangeMinimumFrameRateAfterWarmup"
        />
        <span style="margin-left: 10px"
          >{{ minimumFrameRateAfterWarmup }}帧</span
        >
      </div>
      <div class="input-wraper">
        <span style="width: 120px">最大帧数:</span>
        <el-slider
          style="width: 250px"
          :step="1"
          :min="0"
          :max="60"
          v-model="targetFrameRate"
          size="small"
          @input="onChangeTargetFrameRate"
        />
        <span style="margin-left: 10px">{{ targetFrameRate }}帧</span>
      </div>
      <div style="text-align: end">
        <el-button type="primary" @click="close">关闭警报</el-button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { onMounted, onUnmounted, reactive, ref, markRaw } from "vue";
import SvgIcon from "../components/SvgIcon.vue";
import { setRequestRenderMode } from "../../static/CIM/BQGIS-manuallyRender";
const isShow = ref(false);

let frameRateMonitor;
const minimumFrameRateAfterWarmup = ref(8); // 报警触发阈值
const resolutionScale = ref(viewer.viewer.resolutionScale);
const targetFrameRate = ref(viewer.viewer.targetFrameRate);
const frameRate = ref();
const warnFrame = ref();
const tableData = ref([]);

init();

function init() {
  frameRateMonitor = Cesium.FrameRateMonitor.fromScene(viewer.scene);
  frameRateMonitor.minimumFrameRateAfterWarmup =
    minimumFrameRateAfterWarmup.value;
  viewer.scene.postRender.addEventListener(postRender);
  frameRateMonitor.lowFrameRate.addEventListener(warning);
}

function close() {
  setRequestRenderMode(true);
  viewer.scene.postRender.removeEventListener(postRender);
  frameRateMonitor.lowFrameRate.removeEventListener(postRender);
  tableData.value.forEach((item) => {
    item.layer.tileset.tileLoad.removeEventListener(getTileConfig);
    item.layer.tileset.tileUnload.removeEventListener(getTileConfig);
  });
  tableData.value = [];
  isShow.value = false;
}

function postRender() {
  frameRate.value = frameRateMonitor.lastFramesPerSecond
    ? Number(frameRateMonitor.lastFramesPerSecond).toFixed(2)
    : null;
}

function warning(d, frameRate) {
  if (tableData.value.length) return; // 避免重复触发
  setRequestRenderMode(false);
  const layers = viewer.getLayers();
  if (!layers || !layers.length) return;
  layers.forEach((layer) => {
    if (layer.type === "3dtiles" && layer.tileset) {
      tableData.value.push({
        id: layer.id,
        name: layer.name,
        layer: markRaw(layer),
        maximumScreenSpaceError: 128 - layer.tileset.maximumScreenSpaceError,
        maximumMemoryUsage: layer.tileset.maximumMemoryUsage,
        size: formatSizeInBytes(layer.tileset.totalMemoryUsageInBytes) || 0,
      });
      layer.tileset.tileLoad.addEventListener(getTileConfig.bind(null, layer));
      layer.tileset.tileUnload.addEventListener(
        getTileConfig.bind(null, layer)
      );
    }
  });
  warnFrame.value = frameRate ? Number(frameRate).toFixed(2) : null;
  isShow.value = true;
}

function getTileConfig(layer) {
  console.log(layer, "layer");
  const layerData = tableData.value.find((item) => item.id == layer.id);
  if (!layerData) return;
  layerData.size = formatSizeInBytes(layer.tileset.totalMemoryUsageInBytes);
}

function formatSizeInBytes(size) {
  if (!size) return "";
  const num = 1024.0; //byte
  if (size < num) {
    return size + "B";
  } else if (size < Math.pow(num, 2)) {
    return (size / num).toFixed(5) + "KB"; //kb
  } else if (size < Math.pow(num, 3)) {
    return (size / Math.pow(num, 2)).toFixed(5) + "MB";
  } else if (size < Math.pow(num, 4)) {
    return (size / Math.pow(num, 3)).toFixed(5) + "G"; //G
  } else {
    return (size / Math.pow(num, 4)).toFixed(5) + "T";
  }
}

function changeProperty(data, row, key) {
  row.layer.tileset[key] = data;
  if (viewer.scene.requestRenderMode) {
    viewer.scene.requestRender();
  }
}

function changeMaximumScreenSpaceError(data, row) {
  row.layer.tileset.maximumScreenSpaceError = 128 - data;
  if (viewer.scene.requestRenderMode) {
    viewer.scene.requestRender();
  }
}

function onChangeMinimumFrameRateAfterWarmup(data) {
  frameRateMonitor.minimumFrameRateAfterWarmup = data;
}

function onChangeResolutionScale(data) {
  viewer.viewer.resolutionScale = data;
  if (viewer.scene.requestRenderMode) {
    viewer.scene.requestRender();
  }
}

function onChangeTargetFrameRate(data) {
  viewer.viewer.targetFrameRate = data;
  if (viewer.scene.requestRenderMode) {
    viewer.scene.requestRender();
  }
}

function setModel() {}
</script>

<style lang="scss" scoped>
.popup {
  position: absolute;
  top: 10%;
  left: 50%;
  translate: -50%;
  width: 1000px;
  background: linear-gradient(
    180deg,
    rgba(36, 7, 7, 0.9) 0%,
    rgba(0, 0, 0, 0.3) 100%
  );
  border: 1px solid #acd38f;
  border-radius: 6px;
  color: #acd38f;
  padding: 10px;
  font-size: 14px;
  .popup_header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    color: #fff;
    color: #acd38f;
  }
  .input-wraper {
    display: flex;
    align-items: center;
    color: #acd38f;
  }
  .input {
    color: #fff;
    width: 40px;
  }
  :deep(.el-input__wrapper) {
    background: transparent;
    box-shadow: none;
    padding: 0;
  }
  :deep(.el-input__inner) {
    background: transparent;
    color: #fff;
    border: none;
    box-shadow: none;
    padding: 0;
  }
  :deep(.is-focus) {
    border: none;
    box-shadow: none;
    padding: 0;
  }
  .popup_body {
    margin: 10px;
    .table {
      height: calc(100% - 60px);
      background-color: transparent;
      color: #fff;
      overflow: auto;

      :deep(.table-row) {
        background-color: transparent !important;
      }

      :deep(.table-cell) {
        background-color: transparent !important;
      }

      :deep(.table-header-row) {
        background-color: transparent !important;
      }

      :deep(.table-header-cell) {
        background-color: transparent !important;
        color: #fff;
      }
    }
  }
  .tile-list {
    .row {
      display: flex;
    }
  }

  .wide {
    width: 505px;
  }
}
.info {
  margin-top: 20px;
}
.flex-center {
  display: flex;
  align-items: center;
}
.el-button {
  height: 30px;
  background: transparent;
  border: 1px solid #acd38f;
  color: #acd38f;
  border-radius: 4px;
  padding: 8px 20px;
}
</style>